package com.example.system.security.service;

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.data.redis.core.RedisTemplate;
import com.example.system.security.util.JwtTokenUtil;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;

import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class AuthService {
    
    @Autowired
    private CustomUserDetailsService userDetailsService;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    
    @Autowired
    private RsaService rsaService;
    
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    
    public Map<String, Object> login(String username, String rawPassword) {
        UserDetails userDetails = userDetailsService.loadUserByUsername(username);
        
        String decryptedPassword;
        try {
            decryptedPassword = rsaService.decrypt(rawPassword);
        } catch (Exception e) {
            throw new BadCredentialsException("密码解析失败", e);
        }
        
        if (!passwordEncoder.matches(decryptedPassword, userDetails.getPassword())) {
            throw new BadCredentialsException("用户名或密码错误");
        }
        
        UsernamePasswordAuthenticationToken authenticationToken =
            new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        
        
        String token = jwtTokenUtil.generateToken(userDetails);
        
        // 如果已有token，先删除旧token
        String oldTokenKey = "login:token:" + username;
        if (redisTemplate.hasKey(oldTokenKey)) {
            redisTemplate.delete(oldTokenKey);
        }
        // 保存新token
        redisTemplate.opsForValue().set(oldTokenKey, token, jwtTokenUtil.getExpiration(),
            TimeUnit.MILLISECONDS);
        
        Map<String, Object> userInfo = Map.of(
            "username", userDetails.getUsername(),
            "authorities", userDetails.getAuthorities()
        );
        
        return Map.of(
            "token", token,
            "user", userInfo
        );
    }
    
}
